﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;



namespace WordMine
{
    class PlayScene : InteractableScene
    {
        #region constants
        //Background Positions
        private const int BACKGROUND_OFFSET_X = 400;
        private const int BACKGROUND_OFFSET_Y = 240;

        private const int TRACK_OFFSET_X = 320;
        private const int TRACK_OFFSET_Y = 240;
        private const int TRACK_SPACING_X = 70;

        private const int TRACK_STOP_OFFSET_X = 323;
        private const int TRACK_STOP_OFFSET_Y = 465;
        private const int TRACK_STOP_SPACING_X = 70;

        private const int LEVEL_BAR_OFFSET_X = 235;
        private const int LEVEL_BAR_OFFSET_Y = 280;

        //Menu Positions
        private const int SIDEBAR_OFFSET_X = 105;
        private const int SIDEBAR_OFFSET_Y = 240;

        private const int MINER_OFFSET_X = 105;
        private const int MINER_OFFSET_Y = 360;

        private const int BUTTON_BONUS_OFFSET_X = 95;
        private const int BUTTON_BONUS_OFFSET_Y = 40;

        private const int BUTTON_SCORE_OFFSET_X = 95;
        private const int BUTTON_SCORE_OFFSET_Y = 110;

        private const int BUTTON_WORD_OFFSET_X = 95;
        private const int BUTTON_WORD_OFFSET_Y = 180;

        private const int BUTTON_MENU_OFFSET_X = 95;
        private const int BUTTON_MENU_OFFSET_Y = 250;

        //Play Area Positions
        private const int CART_OFFSET_X = 320;
        private const int CART_OFFSET_Y = 40;
        private const int CART_OFFSET_ODD_Y = 40;
        private const int CART_SPACING_X = 57;
        private const int CART_SPACING_Y = 78;

        //Game Parameters
        private const int CART_MIN_ROWS = 5;
        private const int CART_MAX_ROWS = 6;
        private const int CART_COLUMNS = 7;

        private const int CART_SPEED_START_GAME = 150;
        private const int CART_SPEED_PLAYING_GAME = 5;

        private const int ONE_NUGGET_VALUE = 25;
        private const int TWO_NUGGET_VALUE = 50;
        private const int THREE_NUGGET_VALUE = 100;
        #endregion
        //Scoring

        private Dictionary<String, int> wordsMade;

        //Background GameObjects
        private GameObject background;
        public LevelBar levelBar;
        private int maxTimer;
        //Menu GameObjects
        private GameObject sideBar;
        private GameObject miner;
        private TokenGameObject buttonMenu;
        int timer;
        private String mode;
        //Play Area GameObjects
        public MineCart[,] mineCarts;
        private List<AnimatedInteractableGameObject> explosions;
        private List<MineCart> lastMineCarts;

        private PopupScoreScene popupScoreScene;
        private PopupMenuScene popupMenuScene;
        private PopupLoseScene popupLoseScene;
        //Game Data
        private Random rand;

        private String language;

        public Player1 player1;
        public Player2 player2;
        public BattleScene battleScene;
        public PlayScene()
            : base()
        {
            this.sceneIndex = SceneIndex.PlayScene;
        }

        public override void Stop()
        {
            base.Stop();
            //Background GameObjects
            background = null;
            levelBar = null;

            //Menu GameObjects
            sideBar = null;
            miner = null;
            buttonMenu = null;

            //Play Area GameObjects
            mineCarts = null;

            explosions = null;
            lastMineCarts = null;
            popupScoreScene = null;
            popupMenuScene = null;
            popupLoseScene = null;
        }

        public override void Start()
        {
            base.Start();
            lose = false;
          

            //Game Data Initialization
            rand = new Random();
            if (this.options != null)
            {
                this.options.TryGetValue("language", out this.language);
                this.options.TryGetValue("modes", out this.mode);
            }
            battleScene = new BattleScene();
            player1 = new Player1(this.language, this.mode);
            Thread.Sleep(1000);
            player2 = new Player2(this.language, this.mode);
            maxTimer = 60000;
            if (mode == "endless")
                maxTimer /= 2;
            popupScoreScene = new PopupScoreScene();
            popupMenuScene = new PopupMenuScene();
            popupLoseScene = new PopupLoseScene();
            wordsMade = new Dictionary<String, int>();
            //Background Initialization
            background = new GameObject("background/playScene22", new Vector2(BACKGROUND_OFFSET_X, BACKGROUND_OFFSET_Y));
            background.zindex = 0.1f;
            gameObjects.Add(background);

            //Menu Initialization
            buttonMenu = new TokenGameObject("menu/buttonMenu2", new Vector2(BUTTON_MENU_OFFSET_X, BUTTON_MENU_OFFSET_Y), "Menu");
            buttonMenu.zindex = 3f;
            buttonMenu.noAnimate = true;
            buttonMenu.fontPath = "fonts/WesternSmall";
            //gameObjects.Add(buttonMenu);

            sideBar = new GameObject("menu/sidebar2", new Vector2(SIDEBAR_OFFSET_X, SIDEBAR_OFFSET_Y));
            sideBar.zindex = 0f;
           // gameObjects.Add(sideBar);

            miner = new GameObject("menu/miner2", new Vector2(MINER_OFFSET_X, MINER_OFFSET_Y));
            miner.zindex = 0f;
            gameObjects.Add(miner);

            //Play Area Initialization
        }

        public override void LoadContent(ContentManager content)
        {
            this.popupScoreScene.LoadContent(content);
            this.popupMenuScene.LoadContent(content);
            this.popupLoseScene.LoadContent(content);
            player1.LoadContent(content);
            player2.LoadContent(content);
            battleScene.LoadContent(content);
            base.LoadContent(content);
        }

        public override void Update(GameTime gameTime)
        {
#if WINDOWS_PHONE
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            {
                this.control = SceneControls.Goto;
                this.sceneIndex = SceneIndex.MenuScene;
                this.end = true;
            }
#endif
            if (!this.popupScoreScene.dismissed)
            {
                this.popupScoreScene.Update(gameTime);
            }
            else if (!this.popupMenuScene.dismissed)
            {
                this.popupMenuScene.Update(gameTime);
                if (this.popupMenuScene.exit)
                {
                    this.control = SceneControls.Goto;
                    this.sceneIndex = SceneIndex.MenuScene;
                    this.end = true;
                }
                else if (this.popupMenuScene.newGame)
                {
                    this.control = SceneControls.Reset;
                    this.end = true;
                }
            }
            else if (!this.popupLoseScene.dismissed)
            {
                this.popupLoseScene.Update(gameTime);
                if (this.popupLoseScene.newGame)
                {
                    this.control = SceneControls.Reset;
                    this.end = true;
                }
            }
            else
            {

                if (clicked == buttonMenu)
                {
                    this.popupMenuScene.dismissed = false;
                }
                //Lose Game
                timer += gameTime.ElapsedGameTime.Milliseconds;
                if (timer < maxTimer)
                {
                    player1.Update(player1.sendLetters(), gameTime);
                    player2.Update(player2.sendLetters(), gameTime);
                }
                else
                {
                    player1.sendLetters();
                    player2.sendLetters();
                    player1.Update(0, gameTime);
                    player2.Update(0, gameTime);
                }
                foreach (Unit unit in player1.Units)
                    battleScene.generatePlayer1Unit(unit);
                player1.Units.RemoveRange(0, player1.Units.Count());
                foreach (Unit unit in player2.Units)
                    battleScene.generatePlayer2Unit(unit);
                player2.Units.RemoveRange(0, player2.Units.Count());
                battleScene.Update(gameTime);
                if (battleScene.checkForEndOfRound()&&timer>maxTimer)
                {
                    player1.Reset();
                    player2.Reset();

                    timer = 0;
                }
                if (battleScene.player1Base.hp<=0)
                {
                    var sortedDict = (from entry in player1.wordsMade orderby entry.Value descending select entry);
                    this.popupLoseScene.fillIn(player1.longestWord, player1.highestPointWord, player1.highestPointWordScore, sortedDict.ElementAt(0).Key, sortedDict.ElementAt(0).Value, player1.wordsMade.Count);
                    this.popupLoseScene.dismissed = false;
                }
                else if (battleScene.player2Base.hp <= 0)
                {
                    var sortedDict = (from entry in player1.wordsMade orderby entry.Value descending select entry);
                    this.popupLoseScene.fillIn(player2.longestWord, player2.highestPointWord, player2.highestPointWordScore, sortedDict.ElementAt(0).Key, sortedDict.ElementAt(0).Value, player2.wordsMade.Count);
                    this.popupLoseScene.dismissed = false;
                }
                base.Update(gameTime);
            }
        }

        public override void Draw(SpriteBatch spriteBatch)
        {
            if (!this.popupScoreScene.dismissed)
            {
                this.popupScoreScene.Draw(spriteBatch);
            }
            else if (!this.popupMenuScene.dismissed)
            {
                this.popupMenuScene.Draw(spriteBatch);
            }
            else if (!this.popupLoseScene.dismissed)
            {
                this.popupLoseScene.Draw(spriteBatch);
            }
            player1.Draw(spriteBatch);
            player2.Draw(spriteBatch);
            battleScene.Draw(spriteBatch);
            base.Draw(spriteBatch);
        }
    }
}